package com.kk.xhr.kafka.producer.impl;

import com.kk.xhr.kafka.producer.IKafkaProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.List;

/**
 * Kafka Producer
 *
 * @author liujingcheng
 * @version 1.0, 2020/3/11 18:59
 * @since 1.0.0
 */
@Slf4j
@Component
public class KafkaProducerImpl implements IKafkaProducer {
    private final KafkaTemplate<String, String> kafkaTemplate;

    @Autowired
    public KafkaProducerImpl(KafkaTemplate<String, String> kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ListenableFuture<SendResult<String, String>> sendMessage(String topic, String message) {
        return kafkaTemplate.send(topic, message);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ListenableFuture<SendResult<String, String>> sendMessage(String topic, String key, String message) {
        return kafkaTemplate.send(topic, key, message);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sendMessages(List<Pair<String, String>> topicContents) {
        for (Pair<String, String> topicContent : topicContents) {
            log.debug("Send message [{}] to kafka", topicContent);
            kafkaTemplate.send(topicContent.getLeft(), topicContent.getRight());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sendMessagesTransaction(List<Pair<String, String>> topicContents) {
        kafkaTemplate.executeInTransaction(s -> {
            for (Pair<String, String> topicContent : topicContents) {
                log.debug("Send message [{}] to kafka", topicContent);
                s.send(topicContent.getLeft(), topicContent.getRight());
            }
            return true;
        });
    }
}
